package cn.dj.pet.service.impl;

import cn.dj.basic.exception.BusinessException;
import cn.dj.basic.service.BaiduAiAuditService;
import cn.dj.basic.util.*;
import cn.dj.order.domain.OrderPetAcquisition;
import cn.dj.order.mapper.OrderPetAcquisitionMapper;
import cn.dj.org.domain.Employee;
import cn.dj.org.domain.Shop;
import cn.dj.org.mapper.EmployeeMapper;
import cn.dj.org.mapper.ShopMapper;
import cn.dj.pet.domain.SearchMasterMsg;
import cn.dj.pet.domain.SearchMasterMsgAuditLog;
import cn.dj.pet.dto.MsgDto;
import cn.dj.pet.mapper.SearchMasterMsgAuditLogMapper;
import cn.dj.pet.mapper.SearchMasterMsgMapper;
import cn.dj.pet.query.SearchMasterMsgQuery;
import cn.dj.pet.service.ISearchMasterMsgService;
import cn.dj.basic.service.impl.BaseServiceImpl;
import cn.dj.user.domain.Logininfo;
import cn.dj.user.domain.User;
import cn.dj.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 业务实现类：寻主消息
 */
@Service
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements ISearchMasterMsgService {
    @Autowired//注入
    private UserMapper userMapper;
    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;
    @Autowired
    private SearchMasterMsgAuditLogMapper searchMasterMsgAuditLogMapper;
    @Autowired
    private BaiduAiAuditService baiduAiAuditService;
    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private OrderPetAcquisitionMapper orderPetAcquisitionMapper;

    @Override
    @Transactional
    public AjaxResult publish(SearchMasterMsg msg, HttpServletRequest request) {
      /*  id - 自增长
          title - 来自前端页面 - 需要审核
          state - 实体类默认值0
          name - 来自前端页面  - 需要审核
          age - 来自前端页面
          gender - 来自前端页面
          coat_color - 来自前端页面
          resources - 来自前端页面 - 不做
          pet_type - 来自前端页面
          price
          address - 来自前端页面 - 优化 - 百度地图 - 输入提示
          user_id - request
          shop_id - 分配了最近的店铺之后就可以添加【哪个店铺去收购用户发布的寻主消息中的宠物】
          note - 备注
       */

        //1.添加到数据库
            //先根据请求获取登陆信息-  为了拿到user_id
        Logininfo logininfo = LoginContext.getLogininfo(request);
        User user = userMapper.loadByLogininfoId(logininfo.getId());
        msg.setUserId(user.getId());
        searchMasterMsgMapper.save(msg);//得到自增id

        //2.百度AI智能审核
        Boolean boo1 = baiduAiAuditService.textAudit(msg.getName() + msg.getTitle());
        Boolean boo2 = baiduAiAuditService.imageAudit(msg.getResources());//虽然我们项目没有做，但是也要走形式审核一下
        if (boo1 && boo2){//审核通过- 添加日志
            msg.setState(1);//改状态 - 审核通过待处理
            //添加审核日志
            SearchMasterMsgAuditLog log = new SearchMasterMsgAuditLog();
            log.setMsgId(msg.getId());
            log.setState(1);//审核成功 - 日志
            log.setNote("审核通过");
            searchMasterMsgAuditLogMapper.save(log);
            //获取离用户最近的店铺
            Point point = DistanceUtils.getPoint(msg.getAddress());
            Shop nearestShop = DistanceUtils.getNearestShop(point, shopMapper.loadAll());
            if (nearestShop!=null){//找到了最近的店铺
                //设置shop_id
                msg.setShopId(nearestShop.getId());
                //发消息给店铺
//                SmsUtils.sendSms(nearestShop.getTel(),"你有新的订单，请尽快去"+msg.getAddress()+"接宠物！");
                System.out.println("你有新的订单，请尽快去" + msg.getAddress() + "接宠物！");
            }else {//50公里内，没有找到合适的最近的店铺
                msg.setState(3);//放到寻主池 - 1.没有最近的店铺 2.被拒单了
                //发消息 - 用户
//                SmsUtils.sendSms(nearestShop.getTel(),"你附近暂时没有合适的店铺，请敬请期待！");
                System.out.println("你附近暂时没有合适的店铺，请敬请期待！");
            }
                searchMasterMsgMapper.update(msg);//找到店铺就是更新的shop_id,没有就是更新的状态
                //return 前端
                return new AjaxResult();
        }else {//审核不通过 - 添加日志
            //添加审核日志
            SearchMasterMsgAuditLog log = new SearchMasterMsgAuditLog();
            log.setNote("审核失败");
            log.setState(0);
            log.setMsgId(msg.getId());//记住该寻主信息id，以防重复发布了，但审核失败的寻主信息要删除
            searchMasterMsgAuditLogMapper.save(log);
            //发消息 - 用户
//                SmsUtils.sendSms(nearestShop.getTel(),"你附近暂时没有合适的店铺，请敬请期待！");
            System.out.println("寻主消息发布失败，请修改后重新发布！");
            //删除寻主消息
            searchMasterMsgMapper.del(msg.getId());
            //return 前端
            return AjaxResult.me().setSuccess(false).setMsg("寻主消息发布失败，请修改后重新发布！");
        }
        //2.1 审核失败 ：a.改状态-1 b。添加审核日志 c.短信告诉用户寻主消息审核失败 d.响应给前端发布寻主消息失败 - 审核失败    删除
        //2.2 审核成功： a.找到最近的店铺 b.改状态1和shop_id  c.添加审核日志  d.响应给前端  e.发短信告诉店铺管理员有新的订单
    }

    @Override
    public PageList<SearchMasterMsg> user(SearchMasterMsgQuery query, HttpServletRequest request) {
        //用户查询自己的寻主消息 - 需要设置user_id
        Logininfo logininfo = LoginContext.getLogininfo(request);
        User user = userMapper.loadByLogininfoId(logininfo.getId());
        query.setUserId(user.getId());
        return super.queryPage(query);//分页查询 - 只是查询出来的数据有条件的限制 - 动态sql
    }

    @Override
    public PageList<SearchMasterMsg> finish(SearchMasterMsgQuery query, HttpServletRequest request) {
        //查询已完成的寻主消息 - 需要区分管理员
        query.setState(2);//先设置寻主消息状态
        Logininfo logininfo = LoginContext.getLogininfo(request);
        Employee employee = employeeMapper.loadByLogininfoId(logininfo.getId());
        if (employee.getShop_id()!=null){//店铺管理员
            query.setShopId(employee.getShop_id());
        }
        return super.queryPage(query);
    }

    @Override
    public PageList<SearchMasterMsg> toSearchMasterPool(SearchMasterMsgQuery query, HttpServletRequest request) {
       //查询寻主池寻主消息
        query.setState(3);//寻主池里面的，消息状态为3
        return super.queryPage(query);//调用父类中分页+高级查询的方法，设置了特定的状态 - 相当于高级查询-只查询满足条件的数据
    }

    @Override
    public PageList<SearchMasterMsg> toHandle(SearchMasterMsgQuery query, HttpServletRequest request) {
        //查询待处理的寻主消息 - 需要区分管理员
        query.setState(1);//先设置寻主消息状态
        Logininfo logininfo = LoginContext.getLogininfo(request);
        Employee employee = employeeMapper.loadByLogininfoId(logininfo.getId());
        if (employee.getShop_id()!=null){//店铺管理员
            query.setShopId(employee.getShop_id());
        }
        return super.queryPage(query);
    }

    @Override
    public void reject(Long id) {
        //拒单：寻主消息已经分配给某一个店铺。店铺因为某一些原因不想接单
        //拒单之后：放入寻主池 - state改成3，置空店铺id【因为先前分配给店铺的时候设置了shop_id】
        searchMasterMsgMapper.reject(id);
    }

    @Override
    public void accept(MsgDto msgDto) {
        //平台将寻主消息分配给了你这个店铺
        //店铺接收了，指派一个人去接宠物

        //判断订单是否已经存在了 - 说明已经有人去处理了 - 不应该重复接单
        //2天内没有去接宠物 - 将寻主消息派给其他的店铺【msgid订单，state=-1 - 订单会取消了】
        OrderPetAcquisition order =  orderPetAcquisitionMapper.loadByMsgId(msgDto.getMsgId());//返回一个收购订单的对象
        //所以这个判断是为了防止 msgid订单，state=-1 - 订单取消的情况
        //订单还没过期 - 存在 的判断：
        if (order!=null && order.getState()==0){//有订单，并且当前订单是待处理 - 处理请求(又)来了     //根据寻主消息id找到了该订单
            throw  new BusinessException("订单正在处理，请勿重复接单！！");//防止接单冲突
        }
                //还没创建收购订单 - 第一次接单或者先前一次的订单超过2天过期了
        //1.生成收购订单
        SearchMasterMsg msg = searchMasterMsgMapper.loadById(msgDto.getMsgId());
        OrderPetAcquisition newOrder = createOrder(msg,msgDto);
        orderPetAcquisitionMapper.save(newOrder);


        //2.告诉处理人在规定时间内去接回宠物：发短信 规定2天(day)
//        Employee employee = employeeMapper.loadById(msgDto.getHandler());//因为不发短信，所以注释掉 - 没有短信次数了
//        SmsUtils.sendSms(employee.getPhone(),"您有新的订单，请在2天之内去"+msg.getAddress()+"接回宠物");
        System.out.println("您有新的订单，请在2天之内去" + msg.getAddress() + "接回宠物");
    }

    private OrderPetAcquisition createOrder(SearchMasterMsg msg, MsgDto msgDto) {
        OrderPetAcquisition order = new OrderPetAcquisition();
        order.setOrderSn(CodeGenerateUtils.generateOrderSn(msg.getUserId()));//通过用户id创建一个订单编号
        order.setDigest(msgDto.getNote());
        //最后确认时间 - 2天之后的此刻:加2天的时间
        order.setLastcomfirmtime(new Date(System.currentTimeMillis()+2*24*60*60*1000));//毫秒数
        order.setPrice(msg.getPrice());//成本价格
//        order.setPaytype(0);//支付方式 - 去用户那里才去设置
        //state不用管，还是待处理-  要人工去处理之后再说
//        order.setState(); //正在处理，待处理就是0 - 实体类中默认值
//        order.setPetId(); // 也没有 - 宠物接回来之后才会有
        order.setUserId(msg.getUserId());
        order.setShopId((msg.getShopId()));
        order.setAddress(msg.getAddress());
        order.setEmpId(msgDto.getHandler());
        order.setSearchMasterMsgId(msg.getId());
        return order;

    }
}
